package tests;

import static org.junit.Assert.assertEquals;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import papers.Manuscript;
import users.Author;
import users.ProgramChair;
import users.Reviewer;

import java.security.SecureRandom;
import java.math.BigInteger;

/**
 * Tests the methods in the program chair class
 * @author Dickson Kwong
 */
public class TestProgramChair {
	/**
	 * The program chair
	 */
	private ProgramChair my_programchair;
	
	/**
	 * The reviewer
	 */
	private Reviewer my_reviewer;
	
	/**
	 * The author
	 */
	private Author my_author;
	
	/**
	 * The program chair name
	 */
	private String pc_name = "Testing";
	
	/**
	 * The reviewer name
	 */
	private String reviewer_name = "Testing_reviewer";
	
	/**
	 * The manuscript to review
	 */	
	private Manuscript my_manuscript_1;
	
	/**
	 * The manuscript to review
	 */	
	private Manuscript my_manuscript_2;
	
	/**
	 * The manuscript to review
	 */	
	private Manuscript my_manuscript_3;
	
	/**
	 * The manuscript to review
	 */	
	private List<Manuscript> my_manuscriptList;
	
	private SecureRandom random = new SecureRandom();
	
	/**
	 * Generate Random String for testing
	 */
	private String randomString() {
		return new BigInteger(130, random).toString(32);
	}
	
	/**
	 * Initializes the Program Chair and Manuscripts
	 */
	@Before
	public void setUp() {
		my_programchair = new ProgramChair(pc_name);
		my_reviewer = new Reviewer(reviewer_name);
		
		my_author = new Author(randomString());
		my_manuscript_1 = new Manuscript(my_author, new Date(), 
				randomString(), new File(randomString()));
		
		my_author = new Author(randomString());
		my_manuscript_2 = new Manuscript(my_author, new Date(), 
				randomString(), new File(randomString()));
		
		my_author = new Author(randomString());
		my_manuscript_3 = new Manuscript(my_author, new Date(), 
				randomString(), new File(randomString()));
		
		my_manuscriptList = new ArrayList<Manuscript>();
		my_manuscriptList.add(my_manuscript_1);
		my_manuscriptList.add(my_manuscript_2);
		my_manuscriptList.add(my_manuscript_3);
	}
	
	/**
	 * Initializes the Author and Manuscripts
	 */
	@After
	public void clear() {
		my_reviewer = new Reviewer(reviewer_name);
	}
	
	/**
	 * Tests the get PC name from the abs. class
	 */
	@Test
	public void testGetProgramChairName() {
		assertEquals("Name is not the same", 
				pc_name, my_programchair.getName());
	}
	
	/**
	 * Tests the AddReviewer with no manuscript
	 */
	@Test
	public void testAddReviewer() {
		assertEquals("Reviewer's name is not the same", 
				my_reviewer.getName(), my_programchair
				.addReviewer(reviewer_name).getName());
		assertEquals("Reviewer's number of manuscript is not the same", 
				my_programchair.addReviewer(reviewer_name).
				getAssignedManuscripts().size(), 0);
	}
	
	/**
	 * Tests the AddReviewer with one manuscript
	 */
	@Test
	public void testAddReviewerWithManuscript() {
		Reviewer reviewer;
		reviewer = my_programchair.addReviewer(reviewer_name, my_manuscript_1);
		
		assertEquals("Reviewer's number of manuscript is not the same", 
				reviewer.getAssignedManuscripts().size(), 1);
		assertEquals("Reviewer's manuscript is not the same", 
				reviewer.getAssignedManuscripts().get(0), my_manuscript_1);
	}
	
	/**
	 * Tests the AddReviewer with a manuscript list
	 */
	@Test
	public void testAddReviewerWithManuscriptList() {
		Reviewer reviewer;
		reviewer = my_programchair.addReviewer(reviewer_name, my_manuscriptList);

		assertEquals("Reviewer's number of manuscripts is not the same", 
				reviewer.getAssignedManuscripts().size(), 
				my_manuscriptList.size());
		assertEquals("Reviewer's manuscript list is not the same", 
				reviewer.getAssignedManuscripts(), my_manuscriptList);

	}
	
	/**
	 * Test getting the role from the PC class
	 */
	@Test
	public void testGetRole() {
		assertEquals("The role is not the same", "Program Chair",
				my_programchair.getRole());
	}
}
